package Model;

import java.util.Random;

public class MonteCarloSimulation {

	private String callputflag;
	private double price;
	private double strike_price;
	private double time_year;
	private double rate;
	private double rate_holding;
	private double volatility;
	private int nsteps;
	private int nsimulations;
	private int evol;

	public MonteCarloSimulation() {
		callputflag="";
		price=0;
		strike_price=0;
		time_year=0;
		rate=0;
		rate_holding=0;
		volatility=0;
		nsteps=0;
		nsimulations=0;
		evol=1;
	}

	public double MonteCarloStandardOption( String callputflag , double price, double strike_price, double time_year,  double rate, double rate_holding, double volatility,  int nsteps, int nsimulations){

		Random rand;
		rand=new Random();
		double dt,st,sum = 0,drift,vsqrdt;
		int i,j,z = 0;

		dt = time_year / nsteps; 
		drift = (rate_holding - Math.pow(volatility, 2) / 2) * dt; 
		vsqrdt = volatility * java.lang.Math.sqrt(dt);

		if(callputflag.equals("c")){ 
			z = 1   ;
		}
		else if (callputflag.equals("p")){ 
			z = -1 ;
		}

		for(i=1;i < nsimulations;i++){
			st = price; 
			this.evol++;
			for(j=1;j < nsteps;j++){
				st = st * java.lang.Math.exp(drift + vsqrdt * rand.nextGaussian()); 
			}
			sum = sum + Math.max( z * (st - strike_price), 0) ;
		}
		return java.lang.Math.exp(-rate * time_year) * (sum / nsimulations) ;
	}

	public void set_parameters(String c, double p,double str, double time,  double r, double rate_hold, double vola,  int n, int nsimu){

		callputflag=c;
		price=p;
		strike_price=str;
		time_year=time; 
		rate=r;
		rate_holding=rate_hold;
		volatility=vola; 
		nsteps=n;
		nsimulations=nsimu;
	}

	public String getCallputflag() {
		return callputflag;
	}



	public void setCallputflag(String callputflag) {
		this.callputflag = callputflag;
	}



	public double getPrice() {
		return price;
	}



	public void setPrice(double price) {
		this.price = price;
	}



	public double getStrike_price() {
		return strike_price;
	}



	public void setStrike_price(double strike_price) {
		this.strike_price = strike_price;
	}



	public double getTime_year() {
		return time_year;
	}



	public void setTime_year(double time_year) {
		this.time_year = time_year;
	}



	public double getRate() {
		return rate;
	}



	public void setRate(double rate) {
		this.rate = rate;
	}



	public double getRate_holding() {
		return rate_holding;
	}



	public void setRate_holding(double rate_holding) {
		this.rate_holding = rate_holding;
	}



	public double getVolatility() {
		return volatility;
	}



	public void setVolatility(double volatility) {
		this.volatility = volatility;
	}



	public int getNsteps() {
		return nsteps;
	}



	public void setNsteps(int nsteps) {
		this.nsteps = nsteps;
	}



	public int getNsimulations() {
		return nsimulations;
	}



	public void setNsimulations(int nsimulations) {
		this.nsimulations = nsimulations;
	}

	public synchronized int get_Evol(){
		return this.evol;
	}
}
